#!/bin/bash
##用途：标准化计划任务执行脚本
##作者：刘兴旺-BarlowLiu
##版本：v0.1
##变更时间：2017年6月22日
##说明： code表示返回值，0正常，1警告，2已知错误，3未知错误，4超时，5初始状态

anynowtime="date +'%Y-%m-%d %H:%M:%S'"
NOW="echo [\`$anynowtime\`][PID:$$]"
##### 获取传入的计划任务ID 和 超时时间
CRON_ID=$1
TIMEOUT=$2
code=5
##### 确定脚本运行跟路径，即项目路径
WORK_DIR=/var/www
##### 确定运行的命令
CMD="php /var/www/index.php --task=inventories"
##### 获取当前脚本所在路径，及日志路径和文件名，如果不存在就创建
#CRON_DIR=`pwd`
LOG_DIR="${WORK_DIR}/logs/cron"
DATE="date +'%Y-%m-%d'"
[ -d $LOG_DIR ] ||mkdir -p $LOG_DIR
LOG_FILE="${LOG_DIR}/`eval $DATE`_${CRON_ID}.log"
##### 日志接口路径
ADD_URL="https://opsmind.youkeshu.com/crontab/execute/log/add"
UPDATE_URL="https://opsmind.youkeshu.com/crontab/execute/log/update"

##### 添加运行状态到OpsMind
function send_add_status
{
    curl -L -X POST $ADD_URL  -d value="{\"crontab\": ${CRON_ID}, \"start_time\": \"${start_time}\", \"end_time\": \"${end_time}\", \"code\": $code, \"info\": \"$info\"}"
}
##### 更新运行状态
function send_update_status
{
    curl -L -X POST $UPDATE_URL  -d value="{\"crontab\": ${CRON_ID}, \"start_time\": \"${start_time}\", \"end_time\": \"${end_time}\", \"code\": $code, \"info\": \"$info\"}"
}
##### 可在脚本开始运行时调用，打印当时的时间戳及PID。
function job_start
{
    start_time=`eval $anynowtime`
    echo "`eval $NOW` job_start" >>${LOG_FILE}
    ## 判断CURL是否存在，不存在则安装
    ls /usr/bin/curl|| apt-get install curl -y
    cd ${WORK_DIR}
    send_add_status
}

##### 可在脚本执行成功的逻辑分支处调用，打印当时的时间戳及PID。
function job_success
{
    end_time=`eval $anynowtime`
    code=0
    MSG="$*"
    echo "${end_time} job_success:[$MSG]" >>${LOG_FILE}
    send_update_status
    exit $code
}

##### 可在脚本执行警告的逻辑分支处调用，打印当时的时间戳及PID。
function job_warning
{
    end_time=`eval $anynowtime`
    code=1
    MSG="$*"
    echo "${end_time} job_warning:[$MSG]" >>${LOG_FILE}
    send_update_status
    exit $code
}
##### 可在脚本执行严重错误的逻辑分支处调用，打印当时的时间戳及PID。
function job_error
{
    end_time=`eval $anynowtime`
    code=2
    MSG="$*"
    echo "${end_time} job_error:[$MSG]" >>${LOG_FILE}
    send_update_status
    exit $code
}
##### 未知错误处理方式
function job_unknown
{
    end_time=`eval $anynowtime`
    code=3
    MSG="unknown error"
    echo "${end_time} job_error:[$MSG]" >>${LOG_FILE}
    send_update_status
    exit $code
}
##### 可在脚本超时，打印当时的时间戳及PID。
function job_timeout
{
    end_time=`eval $anynowtime`
    code=4
    MSG="The process $PID is over $TIMEOUT seconds!"
    echo "${end_time} job_timeout:[$MSG]" >>${LOG_FILE}
    send_update_status
    exit $code
}
##### 获取日志信息
function get_loginfo
{
    code=`tail -1000 ${LOG_FILE}|grep -w "\"code\"" |tail -1|awk -F\: '{print $2}'|awk -F, '{print $1}'|sed 's/^ //g'`
    info=`tail -1000 ${LOG_FILE}|grep -w "\"info\"" |tail -1|awk -F\: '{print $2}'|sed 's/\"//g'|sed 's/^ //g'`
    if [ $code -gt 5  2>&1 >/dev/null ];then
        code=3
    fi
}
##### 时间控制函数，限制任务执行时长，单位为秒
function timer
{
    TIMEOUT=$1
    CMD=$2
    eval $CMD
    PID=$!
    STIME=0
    while [ $STIME -le $TIMEOUT ]
    do
        ps -A -opid | grep "$PID"
        if [ $? -eq 0 ];then
            if [ $STIME -eq $TIMEOUT ];then
                kill -9 $PID
                job_timeout
                break
            else
                sleep 1
                STIME=`expr ${STIME} + 1`
                echo $STIME;
            fi
        else
            get_loginfo  ##获取日志中的执行状态
            case $code in
                0)
                    job_success $info
                    ;;
                1)
                    job_warning $info
                    ;;
                2)
                    job_error $info
                    ;;
                4)
                    job_timeout
                    ;;
                *)
                    job_unknown
                    ;;
            esac
            break
        fi
    done
}
##### 脚本正式执行启动
job_start
##### 执行计划任务实际内容
timer $TIMEOUT "$CMD >>${LOG_FILE} &"
